package com.vpen.account.demo.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.vpen.account.demo.dao.AccountUserDao;
import com.vpen.account.demo.entity.AccountUser;
import com.vpen.account.demo.handler.AccountDemoException;
import com.vpen.account.demo.model.dto.CodeDto;
import com.vpen.account.demo.model.enums.UserStateEnum;
import com.vpen.account.demo.model.req.ReqAccountUser;
import com.vpen.account.demo.service.AccountUserService;
import com.vpen.account.demo.utils.CodeUtils;
import com.vpen.clib.base.service.BaseServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * (AccountUser)表服务实现类
 *
 * @author vpen
 * @since 2022-08-12 14:01:40
 */
@Slf4j
@Service("accountUserService")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class AccountUserServiceImpl extends BaseServiceImpl<AccountUserDao, AccountUser> implements AccountUserService {
    private final RedissonClient redisson;

    private final PasswordEncoder passwordEncoder;

    public static final String BASE_NUMBER = "01234567899876543210";

    @Override
    public AccountUser selectOneByUsername(String username) {
        return this.lambdaQuery()
                .eq(AccountUser::getUsername, username)
                .eq(AccountUser::getState, UserStateEnum.ENABLE)
                .one();
    }

    @Override
    public AccountUser selectOneByPhone(String phone) {
        return this.lambdaQuery()
                .eq(AccountUser::getPhone, phone)
                .eq(AccountUser::getState, UserStateEnum.ENABLE)
                .one();
    }

    @Override
    public Boolean createUser(ReqAccountUser user) {
        // 1.校验短信验证码
        if (!CodeUtils.validCode(user.getPhone(), user.getCode())) {
            return false;
        }

        // 2.生成随机密码
        String password = user.getUsername() + RandomUtil.randomString(6);
        String passwordEncode = passwordEncoder.encode(password);
        log.debug("随机密码：{}", password);

        // 3.保存信息
        AccountUser accountUser = new AccountUser();
        BeanUtils.copyProperties(user, accountUser);
        accountUser.setPassword(passwordEncode)
                .setState(UserStateEnum.ENABLE);
        return save(accountUser);
    }


    @Override
    public String genCode(String phone) {
        RBucket<CodeDto> codeBucket = redisson.getBucket(phone);

        // 60秒内是否已经发送过验证码
        if (codeBucket.isExists() && CodeUtils.validTime(codeBucket.get().getTimeStamp())) {
            throw new AccountDemoException("验证码已经发送，60秒后重新获取");
        }

        // 1.生成验证码
        CodeDto codeDto = CodeUtils.getRandomNum();

        // 2.发送到手机 TODO:需要阿里云短信验证功能
        log.debug("发送到手机号：{},验证码：{}", phone, codeDto);

        // 3.保存到redis,用于验证,验证码三十分钟过期
        codeBucket.setAsync(codeDto, 30, TimeUnit.MINUTES);
        return codeDto.getCode();
    }

}

